<template>
  <view
    :class="['g-steps', `g-steps-${direction}`]"
    :id="stepsId"
    :style="{
      '--width': steps.length > 4 ? '200rpx' : 750 / steps.length + 'rpx',
      '--margin': dotMargin + 'px',
      '--lineHeight': lineHeight + 'px',
      'flex-direction': reverse
        ? direction == 'row'
          ? 'row-reverse'
          : 'column-reverse'
        : direction,
      '--line': line == 'dashed' ? '60%' : '100%',
    }"
  >
    <view
      v-for="(step, index) in steps"
      :key="index"
      class="g-steps-item"
      :id="index"
      :style="{
        '--textColor': current >= index ? '#323233' : inactiveColor,
        '--dotColor': current >= index ? dotColor : inactiveColor,
        '--dotAround': current >= index ? dotColor + '29' : inactiveColor + '29',
        '--lineColor': inactiveColor,
      }"
    >
      <view class="g-dot"></view>
      <view class="g-steps-label">{{ step[keyName] }}</view>
      <view
        class="g-steps-content"
        :style="{
          paddingBottom: slotHeight[index] * 2 + 88 + 'rpx',
        }"
      >
        <slot :name="`step${index + 1}`" :scope="step"></slot>
      </view>
    </view>
  </view>
</template>

<script>
export default {
  props: {
    // 方向
    direction: {
      type: String,
      default: "row",
    },
    // 当前步骤
    current: {
      type: [String, Number],
      default: 0,
    },
    // 步骤列表
    steps: {
      type: Array,
      default: () => [],
    },
    // 节点颜色
    dotColor: {
      type: String,
      default: "#4ea770",
    },
    // 未激活节点颜色
    inactiveColor: {
      type: String,
      default: "#d1d1d1",
    },
    // 倒序
    reverse: {
      type: Boolean,
      default: false,
    },
    // 插槽样式类
    slotClass: {
      type: String,
      default: "",
    },
    // 步骤名称字段
    keyName: {
      type: String,
      default: "label",
    },
    // 步骤器唯一ID, 单个页面重复使用建议填写区分
    stepsId: {
      type: String,
      default: "steps-" + Number(new Date()),
    },
    // 线条solid实线/dashed虚线
    line: {
      type: String,
      default: "dashed",
    },
  },
  data() {
    return {
      dotMargin: 30, // dot的margin
      lineHeight: 0, // 虚线高度
      slotHeight: [], // 所有插槽slot高度
    };
  },
  watch: {
    steps: {
      handler(val) {
        setTimeout(() => {
          this.getSystemInfo();
          this.getSlotHeight();
        }, 0);
      },
      deep: true,
      immediate: true,
    },
  },
  mounted() {
    setTimeout(() => {
      this.getSystemInfo();
      this.getSlotHeight();
    }, 0);
    // 监听窗口变化
    uni.onWindowResize(() => {
      this.getSystemInfo();
      this.getSlotHeight();
    });
  },
  methods: {
    // 获取插槽高度
    getSlotHeight() {
      if (this.direction == "column") {
        uni
          .createSelectorQuery()
          .in(this)
          .selectAll(this.slotClass)
          .boundingClientRect((data) => {
            this.slotHeight = data?.map((item) => item?.height);
          })
          .exec();

        setTimeout(() => {
          this.getLineHight();
        }, 300);
      }
    },

    // 获取dot的margin
    getSystemInfo() {
      uni
        .createSelectorQuery()
        .in(this)
        .select(`#${this.stepsId} > .g-steps-item > .g-dot`)
        .boundingClientRect((data) => {
          this.dotMargin = data?.left || 30;
        })
        .exec();
    },

    // 获取线条高度
    getLineHight() {
      if (this.direction == "column") {
        uni
          .createSelectorQuery()
          .in(this)
          .selectAll(`#${this.stepsId} > .g-steps-item > .g-dot`)
          .boundingClientRect((data) => {
            console.log(data);
            this.lineHeight = Math.abs(data[data.length - 1]?.top - data[0]?.top);
          })
          .exec();
      }
    },
  },
};
</script>

<style lang="scss" scoped>
.g-steps {
  --width: 100%;
  --margin: 15px;
  --dotColor: #4ea770;
  --dotAround: #4ea77029;
  --textColor: #323233;
  --line: 60%;
  --lineHeight: 0;
  --lineColor: #d1d1d1;
  display: flex;
  padding: 30rpx;
  position: relative;
  overflow: hidden;
  .g-steps-item {
    max-width: var(--width);
    min-height: 100rpx;
    display: flex;
    justify-content: center;
    font-size: 24rpx;
    color: var(--textColor);
    position: relative;
  }
}
.g-steps-row {
  flex-direction: row;
  justify-content: space-between;
  &::after {
    content: "";
    position: absolute;
    left: var(--margin);
    right: var(--margin);
    top: 72rpx;
    height: 2rpx;
    background-image: linear-gradient(
      to right,
      var(--lineColor) var(--line),
      transparent 10%
    );
    background-size: 10rpx 2rpx;
  }
  .g-steps-item {
    flex-direction: column;
    align-items: center;
    .g-dot {
      width: 44rpx;
      height: 44rpx;
      background-color: var(--dotAround);
      border-radius: 50%;
      margin: 20rpx auto;
      position: relative;
      z-index: 2;
      &::after {
        position: absolute;
        content: "";
        display: block;
        width: 22rpx;
        height: 22rpx;
        border-radius: 50%;
        left: calc(50% - 11rpx);
        top: calc(50% - 11rpx);
        background-color: var(--dotColor);
      }
    }
    .g-steps-label {
      flex: 1;
    }
  }
  .g-steps-content {
    font-size: 24rpx;
    color: var(--dotColor);
  }
}
.g-steps-column {
  flex-direction: column;
  &::after {
    content: "";
    position: absolute;
    top: var(--margin);
    left: 52rpx;
    width: 2rpx;
    height: var(--lineHeight);
    background-image: linear-gradient(
      to bottom,
      var(--lineColor) var(--line),
      transparent 10%
    );
    background-size: 2rpx 10rpx;
  }

  .g-steps-item {
    justify-content: flex-start;
    .g-dot {
      width: 44rpx;
      height: 44rpx;
      background-color: var(--dotAround);
      border-radius: 50%;
      position: relative;
      z-index: 2;
      &::after {
        position: absolute;
        content: "";
        display: block;
        width: 22rpx;
        height: 22rpx;
        border-radius: 50%;
        left: calc(50% - 11rpx);
        top: calc(50% - 11rpx);
        background-color: var(--dotColor);
      }
    }
    .g-steps-label {
      padding: 6rpx 0 0 20rpx;
    }
  }
}
</style>
